/** @file

  Copyright (C) 2022 - 2023, Phytium Technology Co., Ltd. All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#ifndef _SCPI_H_
#define _SCPI_H_

#define SMC_SCPI_ID  0xC300FFF0

typedef enum {
    SCPI_SET_NORMAL = 0, /* Normal SCPI commands */
    SCPI_SET_EXTENDED    /* Extended SCPI commands */
} SCPI_SET_T;


typedef enum {
    SCPI_HEAD_TYPE_REQ = 0, /* SCPI requeset Header */
    SCPI_HEAD_TYPE_RSP      /* SCPI Response Header */
}SCPI_HEADER_TYPE_T;

enum {
    SCP_OK = 0,     /* Success */
    SCP_E_PARAM,    /* Invalid parameter(s) */
    SCP_E_ALIGN,    /* Invalid alignment */
    SCP_E_SIZE,     /* Invalid Size */
    SCP_E_HANDLER,  /* Invalid handler or callback */
    SCP_E_ACCESS,   /* Invalid access or permission denied */
    SCP_E_RANGE,    /* Value out of range */
    SCP_E_TIMEOUT,  /* Time out has ocurred */
    SCP_E_NOMEM,    /* Invalid memory area or pointer */
    SCP_E_PWRSTATE, /* Invalid power state */
    SCP_E_SUPPORT,  /* Feature not supported or disabled */
    SCPI_E_DEVICE,  /* Device error */
    SCPI_E_BUSY,    /* Device is busy */
    SCPI_E_OS,      /* RTOS error occurred */
    SCPI_E_DATA,    /* unexpected or invalid data received */
    SCPI_E_STATE,   /* invalid or unattainable state reuested */
};

enum SCPI_CMD_ID {
    CMD_ID_SCP_READY = 1,
    CMD_ID_GET_SCP_CAPABILITY,
    CMD_ID_SET_CSS_POWER_STATE,
    CMD_ID_GET_CSS_POWER_STATE,
    CMD_ID_SET_SYSTEM_POWER_STATE,
    CMD_ID_SET_CPU_TIMER,
    CMD_ID_CANCEL_CPU_TIMER,
    CMD_ID_GET_DVFS_CAPABILITY,
    CMD_ID_GET_DVFS_INFO,
    CMD_ID_SET_DVFS,
    CMD_ID_GET_DVFS,
    CMD_ID_GET_DVFS_STATISTICS,
    CMD_ID_GET_CLOCKS_CAPABILITY,
    CMD_ID_GET_CLOCK_INFO,
    CMD_ID_SET_CLOCK_VALUE,
    CMD_ID_GET_CLOCK_VALUE,
    CMD_ID_GET_POWER_SUPPLY_CAPABILITY,
    CMD_ID_GET_POWER_SUPPLY_INFO,
    CMD_ID_SET_POWER_SUPPLY,
    CMD_ID_GET_POWER_SUPPLY,
    CMD_ID_GET_SENSOR_CAPABILITY,
    CMD_ID_GET_SENSOR_INFO,
    CMD_ID_GET_SENSOR_VALUE,
    CMD_ID_CONFIG_PERIODIC_SENSOR_READINGS,
    CMD_ID_CONFIG_SENSOR_BOUNDS,
    CMD_ID_ASYNC_SENSOR_VALUE,
    CMD_ID_SET_DEVICE_POWER_STATE,
    CMD_ID_GET_DEVICE_POWER_STATE,
    CMD_ID_UNKNOW,
};

enum SCPI_EX_CMD_ID{
    CMD_ID_EX_PLL_WARMRESET = 0x81,
    CMD_ID_EX_MODULE_RESET,
    CMD_ID_EX_PEIR_POWER,
    CMD_ID_EX_SET_FREQ      = 0x88,
    CMD_ID_EX_SET_I2C_PORT  = 0x89,
    CMD_ID_EX_SET_VOLTAGE   = 0x8A,
    CMD_ID_EX_UNKNOW,
};

/*
 * An SCPI command consists of a Header and a Payload.
 * The following structure describes the Header. It is 64-bit long.
 */
typedef struct {
    /* Command Id */
    UINT32 Id        : 7;
    /* Set Id. Identifies whether this is a standard or extended command. */
    UINT32 Set       : 1;
    /* Sender Id to match a reply. The value is Sender specific. */
    UINT32 Sender    : 8;
    /* Size of the Payload in bytes (0 - 511) */
    UINT32 Size      : 9;
    UINT32 Reserved  : 7;
    /*
     * Status indicating the success of a command.
     * See the enum below.
     */
    UINT32 Status;
} SCPI_CMD_T;

typedef struct{
    /* 4 byte SCPI protocol Version */
    UINT32 Version;
    /* 4 byte Payload Size Limits */
    UINT32 Limits;
    /* 4 byte Firmware Version */
    UINT32 FirmwareVersion;
    /* 4 Commands enabled 0 */
    UINT32 CmdEnable0;
    /* 4 Commands enabled 1 */
    UINT32 CmdEnable1;
    /* 4 Commands enabled 2 */
    UINT32 CmdEnable2;
    /* 4 Commands enabled 3 */
    UINT32 CmdEnable3;
} PL_SCP_CAPABILITY_T;

typedef struct{
    UINT32 CpuId              : 4;
    UINT32 ClusterId          : 4;
    UINT32 CpuPowerState     : 4;
    UINT32 ClusterPowerState : 4;
    UINT32 CssPowerStat     : 4;
    UINT32 Reserved            : 12;
} PL_REQ_CSS_POWER_STATES_T;

typedef struct{
    UINT32 ClusterId        : 4;  //[3:0] Cluster Id Cluster Id of the current entry.
    UINT32 ClusterPwrState : 4;  //[7:4] Cluster Power State Current cluster power state.
    UINT32 CpuPwrState     : 4;  //[15:8] CPU Power State Current power state of each core belonging to Cluster Id.
} PL_RSP_CSS_POWER_STATES_T;

typedef struct {
    UINT8 SysPwrStat; // System Power State One of the following power states:
} pl_set_system_power_state_t;

typedef struct {
    UINT32 TimestampL;
    UINT32 TimestampH;
    UINT8  CpuId     : 4;
    UINT8  ClusterId : 4;
} PL_SET_CPU_TIMER_T;

typedef struct {
    UINT8 CpuId     : 4;
    UINT8 ClusterId : 4;
} PL_CANCEL_CPU_TIMER_T;

typedef struct {
    UINT8 Count;   // Number of Voltage domains with support for DVFS.
} PL_GET_DVFS_CAPABILITY_T;

typedef struct {
    UINT8 VoltageDomainId;   //Voltage domain being queried.
} PL_GET_DVFS_INFO_REQ_T;

typedef struct {
    UINT32 VoltageDomainId : 8;   //Voltage domain being queried.
    UINT32 NumOpPoints     : 8;   //Number of discrete operating points that are supported.
    UINT32 Latency         : 16;  //Worst case latency in microseconds when switching operating points
    UINT32 Frequency;               //Operating Point Tuple - Frequency in Hertz (Hz)
    UINT32 Voltage;                 //Operating Point Tuple - Voltage in millivolts (mV)
} PL_GET_DVFS_INFO_RSP_T;

typedef struct {
    UINT8 VoltageDomainId;   //Voltage domain being queried.
    UINT8 OperatingPointIdx; //An index in the Operating Point List
} PL_SET_DVFS_T;

typedef struct {
    UINT8 VoltageDomainId;   //Voltage domain being queried.
} PL_GET_DVFS_REQ_T;

typedef struct {
    UINT8 OperatingPointIdx;   //Voltage domain being queried.
} PL_GET_DVFS_RSP_T;

typedef struct {
    UINT8 VoltageDomainId;   //Voltage domain being queried.
} PL_GET_DVFS_STATISTIC_REQ_T;

typedef struct {
    UINT32 NumOperatingPoints  : 8;
    UINT32 Reserv              : 24;
    UINT32 NumOfSwitchs;              //Number of Switches
    UINT32 StartTimestampL;
    UINT32 StartTimestampH;
    UINT32 CurrentTimestampL;
    UINT32 CurrentTimestampH;
    UINT32 RedidencyL;
    UINT32 RedidencyH;
} PL_GET_DVFS_STATISTIC_RSP_T;

typedef struct {
    UINT16 Count;  // number of clocks
} PL_GET_CLOCK_CAP_T;

typedef struct {
    UINT16 ClockId;
} PL_GET_CLOCK_INFO_REQ_T;

typedef struct {
    UINT16 ClockId;
    UINT16 Readable : 1;  //When 1, indicates that the SCP accepts a Get request
    UINT16 Writable : 1;  //When 1, indicates that the SCP accepts a Set request.
    UINT16 Rsv      : 14;
    UINT32 MinRate;      //Minimum Frequency in Hertz (Hz)
    UINT32 MaxRate;      //Maximum Frequency in Hertz (Hz)
    CHAR8  ClockName[20];    //20 single-byte CHAR8acters
} PL_GET_CLOCK_INFO_RSP_T;

typedef struct {
    UINT16 ClockId;
    UINT16 Rsv;
    UINT32 Frequency;  //Frequency in Hertz (Hz)
} PL_SET_CLOCK_VALUE_T;

typedef struct {
    UINT16 ClockId;
} PL_GET_CLOCK_VALUE_REQ_T;

typedef struct {
    UINT32 Frequency;  //Frequency in Hertz (Hz)
} PL_GET_CLOCK_VALUE_RSP_T;

typedef struct {
    UINT16 Count;  //Number of power supplies
} PL_GET_POWER_SUPPLY_CAP_T;

typedef struct {
    UINT16 PowerSupplyId;  //Power Supply Id
} PL_GET_POWER_SUPPLY_INFO_REQ_T;

typedef struct {
    UINT16 PowerSupplyId;  //Power Supply Id
    UINT16 Readable : 1;
    UINT16 Writable : 1;
    UINT16 Rsv      : 14;
    UINT32 MinVoltage;
    UINT32 MaxVoltage;
    UINT8  PwrSupplyName[20];
} PL_GET_POWER_SUPPLY_INFO_RSP_T;

typedef struct {
    UINT16 PowerSupplyId;  //Power Supply Id
    UINT16 Rsv;
    UINT32 Voltage;
} PL_SET_POWER_SUPPLY_T;

typedef struct {
    UINT16 PowerSupplyId;  //Power Supply Id
} PL_GET_POWER_SUPPLY_REQ_T;

typedef struct {
    UINT32 Voltage;
} PL_GET_POWER_SUPPLY_RSP_T;

typedef struct {
    UINT16 Count;
} PL_GET_SENSOR_CAPABILITY_T;

typedef struct {
    UINT16 SensorId;
} PL_GET_SENSOR_INFO_REQ_T;

typedef struct {
    UINT16 SensorId;
    UINT8  SensorClass;
    UINT8  TriggerType;
    UINT8  SensorName[20];
} PL_GET_SENSOR_INFO_RSP_T;

typedef struct {
    UINT16 SensorId;
} PL_GET_SENSOR_VALUE_REQ_T;

typedef struct {
    UINT32 ValueLow;
    UINT32 ValueHigh;
} PL_GET_SENSOR_VALUE_RSP_T;

typedef struct {
    UINT16 SensorId;
    UINT16 Recurrence;  //Specifies how many periodic readings are taken before stopping. The following values are special
    UINT32 Period;      //in ticks
} PL_CONFIG_PERIODIC_SENSOR_READINGS_T;

typedef struct {
    UINT16 SensorId;
    UINT16 Triggers;
    UINT32 LowLimitLeast;
    UINT32 HighLimitLeast;
    UINT32 LowLimitMost;
    UINT32 HighLimitMost;
} PL_CONFIG_SENSOR_BOUNDS_T;

typedef struct {
    UINT16 SensorId;
    UINT16 ReadingId;
    UINT32 ValueLow;   //Least significant 32 bits of the sensor value.
    UINT32 ValueHigh;  //Most significant 32 bits of the sensor value.
} PL_ASYNC_SENSOR_VALUE_T;

typedef struct {
    UINT16 SensorId;
    UINT8  PowerState;  //Most significant 32 bits of the sensor value.
} PL_SET_DEV_POWER_STATE_T;

typedef struct {
    UINT16 SensorId;
} PL_GET_DEV_POWER_STATE_REQ_T;

typedef struct {
    UINT8 PowerState;  //Most significant 32 bits of the sensor value.
} PL_GET_DEV_POWER_STATE_RSP_T;

typedef struct {
    UINT32 PLL_SMM_REAL;
    UINT32 PLL_DMM_REAL;
    UINT32 PLL_GMU_REAL;
    UINT32 PLL_FIO_REAL;
    UINT32 PLL_LMU_REAL;
    UINT32 PLL_NOC_REAL;
    UINT32 PLL_C1_REAL;
    UINT32 PLL_C0_REAL;
} PL_PLL_WARMRESET_T;

typedef struct {
    UINT32 ResetModule;
} PL_MODULE_RESET_T;


typedef struct {
    UINT8  DevId;
    UINT8  PowerState;
    UINT16 Rev;
} PL_PEIR_POWER_T;

#define DVFS_LEVEL_NUM 4
typedef struct {
    UINT8 Mode:1;
    UINT8 I2cPort:3;
    UINT8 Resever:4;
    UINT8 UcDevAddr;
    UINT8 UcWregAddr;
    UINT8 UcRregAddr;
    union {
        UINT8  AucData[DVFS_LEVEL_NUM];
        UINT16 AusData[DVFS_LEVEL_NUM];
    };
} ST_VOLTAGE_T;

typedef struct {
    UINT32 HighTemp;
    UINT32 LowTemp;
    UINT32 Pll0;
    UINT32 Pll1;
    UINT32 Pll2;
    UINT32 Time;
} ST_TEMP_T;

typedef struct {
    UINT8 I2cPort;
} ST_I2C_PORT_T;

#endif /* _SCPI_H_ */
